﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Jemgine.EffectEditor
{
	public partial class TypeSelector : Form
	{
        public System.Type ChoosenType;

		TreeNode FindCategory(string Category)
		{
			foreach (TreeNode Node in treeView.Nodes)
				if (Node.Text == Category) return Node;

			TreeNode newNode = new TreeNode(Category);
			treeView.Nodes.Add(newNode);
			return newNode;
		}

        internal static Object FindComponent(System.Type on, System.Type of)
        {
            var attributes = on.GetCustomAttributes(of, false);
            foreach (var obj in attributes)
                if (obj.GetType() == of) return obj;
            return null;
        }

		public TypeSelector(Config _config, Func<System.Type, bool> Filter)
		{
			InitializeComponent();

            List<TreeNode> MiscNodes = new List<TreeNode>();

            foreach (System.Reflection.Assembly Assembly in _config._loadedAssemblies)
            {
                foreach (System.Type PossibleComponent in Assembly.GetTypes())
                {
                    if (Filter(PossibleComponent))
                    {
                        TreeNode newNode = new TreeNode();
                        newNode.Text = PossibleComponent.Name;
                        newNode.Tag = PossibleComponent;
                        string Category = null;

                        var CategoryAttribute = FindComponent(PossibleComponent, typeof(Engine.CategoryAttribute));
                        if (CategoryAttribute != null) Category = (CategoryAttribute as Engine.CategoryAttribute).Category;

                        if (Category != null) FindCategory(Category).Nodes.Add(newNode);
                        else MiscNodes.Add(newNode);
                    }
                }
            }
            
            foreach (TreeNode Node in MiscNodes)
                treeView.Nodes.Add(Node);

            treeView.Sort();

            this.DialogResult = DialogResult.Cancel;
        }

		private void treeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
		{
			if (e.Node == null || e.Node.Tag == null) return;
            ChoosenType = (System.Type)e.Node.Tag;
            this.DialogResult = DialogResult.OK;
            Close();
		}

        private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node == null || e.Node.Tag == null)
            {
                this.Description.Text = "";
                return;
            }

            ChoosenType = (System.Type)e.Node.Tag;

            var DescriptionAttribute = FindComponent(ChoosenType, typeof(Engine.DescriptionAttribute));
            if (DescriptionAttribute != null)
                this.Description.Text = (DescriptionAttribute as Engine.DescriptionAttribute).Description;
            else
                this.Description.Text = "";



        }

        private void OkButton_Click(object sender, EventArgs e)
        {
            if (treeView.SelectedNode == null || treeView.SelectedNode.Tag == null) return;
            ChoosenType = (System.Type)treeView.SelectedNode.Tag;
            this.DialogResult = DialogResult.OK;
            Close();
        }

        private void CancelButton_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            Close();
        }
	}
}
